/*
 * TabbedPane.cpp
 *
 *  Created on: 12-12-2010
 *      Author: Przemek
 */

#include "gui/TabbedPane.hpp"
#include "gui/UIManager.hpp"
#include "gui/ClipArea.hpp"
#include "utils/GLUtils.hpp"
using namespace std;

TabbedPane::Tab::Tab(const string& name, Control* control) :
	name(name), control(control)
{

}

const string& TabbedPane::Tab::getName() const
{
	return name;
}

Control* TabbedPane::Tab::getControl() const
{
	return control;
}

TabbedPane::TabbedPane() :
	currentTabIndex(-1)
{

}

const float TabbedPane::TABS_HEIGHT = 20.0f;
const float TabbedPane::TABS_OFFSET = 5.0f;

void TabbedPane::add(Control* control, const string& name)
{
	tabs.push_back(Tab(name, control));
	if(currentTabIndex == -1)
	{
		currentTabIndex = 0;
	}
	add(control);
}

void TabbedPane::setBounds(const geometry::Rectangle& bounds)
{
	Container::setBounds(bounds);
	updateAllTabsBounds();
}

void TabbedPane::setSize(const Dimension& size)
{
	Container::setSize(size);
	updateAllTabsBounds();
}

Control* TabbedPane::getDeepestControlAt(const Vector& point, Vector* pointInControlCoordinates)
{
	const Vector& translatedPoint = point - getPosition();
	if(point.getY() < TABS_HEIGHT)
	{
		pointInControlCoordinates->set(translatedPoint);
		return this;
	}

	if(currentTabIndex < 0)
	{
		return Container::getDeepestControlAt(translatedPoint, pointInControlCoordinates);
	}

	Control* candidate = tabs.at(currentTabIndex).getControl();
	Container* container = dynamic_cast<Container*> (candidate);
	if(container != NULL)
	{
		return container->getDeepestControlAt(translatedPoint, pointInControlCoordinates);
	}
	pointInControlCoordinates->set(translatedPoint - candidate->getPosition());
	return candidate;
}

void TabbedPane::draw(const ClipArea& clipArea)
{
	UIManager::getInstance().getTabbedPaneBackgroundColor().setGLState();
	GLUtils::drawRectangle(Vector(0, 0), getSize());

	if(currentTabIndex >= 0)
	{
		for(unsigned int i = 0; i < tabs.size(); ++i)
		{
			drawSingleTab(i);
		}

		Control* control = tabs.at(currentTabIndex).getControl();
		ClipArea controlClipArea = clipArea.getUpdatedByControl(*control);
		controlClipArea.setGLClipArea();
		drawControl(*control, controlClipArea);
	}
}

void TabbedPane::updateAllTabsBounds()
{
	BOOST_FOREACH(Tab tab, tabs)
				{
					Control* control = tab.getControl();
					setNewTabBounds(control);
				}
}

void TabbedPane::setNewTabBounds(Control* control)
{
	const Vector& position = Vector(0.0f, TABS_HEIGHT);
	const Dimension& size = Dimension(getSize().getWidth(), getSize().getHeight() - TABS_HEIGHT);

	control->setBounds(geometry::Rectangle(position, size));
}

void TabbedPane::add(Control* control)
{
	Container::add(control);
	setNewTabBounds(control);
}

void TabbedPane::drawSingleTab(unsigned int i)
{
	const string& name = tabs.at(i).getName();
	const geometry::Rectangle& bounds = getBoundsForTab(i);
	const Vector& position = bounds.getPosition();
	const Dimension& size = bounds.getSize();

	UIManager::getInstance().getTabbedPaneTabColor().setGLState();
	if(currentTabIndex == static_cast<int> (i))
	{
		UIManager::getInstance().getTabbedPaneTabColor().darken(0.3f).setGLState();
	}
	GLUtils::drawRectangle(position, size);

	UIManager::getInstance().getTabbedPaneTabTextColor().setGLState();
	const GLFont& font = UIManager::getInstance().getGUIFont();
	font.begin();
	font.drawTextAt(name, bounds.getLeftCornerForCenteredDimension(font.measureTextSize(name)));
	font.end();
}

geometry::Rectangle TabbedPane::getBoundsForTab(unsigned int i)
{
	const int singleTabWidth = getSize().getWidth() / tabs.size();
	Vector position(i * singleTabWidth, TABS_OFFSET);
	Dimension size(singleTabWidth - 2 * TABS_OFFSET, TABS_HEIGHT - TABS_OFFSET);

	return geometry::Rectangle(position, size);
}

void TabbedPane::mousePressed(const MouseListener::EventArguments& arguments)
{
	for(unsigned int i = 0; i < tabs.size(); ++i)
	{
		if(getBoundsForTab(i).contains(arguments.getPoint()))
		{
			currentTabIndex = static_cast<int> (i);
		}
	}
}
